package com.njworkorder.Controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njworkorder.DTO.MeteringInventoryDTO;
import com.njworkorder.Entity.*;
import com.njworkorder.Service.MeteringInventoryService;
import com.njworkorder.Utils.Result;
import com.njworkorder.Utils.ResultUtil;
import com.njworkorder.VO.MeteringInventoryLevelVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@Tag(name = "计量单位相关接口", description = "计量单位相关接口")
@RestController
@RequestMapping("/met")
public class MeteringInventoryController {

    private final MeteringInventoryService meteringInventoryService;

    public MeteringInventoryController(MeteringInventoryService meteringInventoryService) {
        this.meteringInventoryService = meteringInventoryService;
    }

    @Operation(summary = "获取计量单位列表")
    @GetMapping("/getMetList")
    public Result<Page<MeteringInventory>> getCIList(@RequestParam("pageIndex") int pageIndex, @RequestParam("pageSize") int pageSize, @RequestParam(value = "pricingType", required = false) String pricingType, @RequestParam(value = "projectName", required = false) String projectName) {
        LambdaQueryWrapper<MeteringInventory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.apply("1=1")

                .eq(projectName != null && !projectName.isEmpty(), MeteringInventory::getProjectName, projectName)
                .eq(pricingType != null && !pricingType.isEmpty(), MeteringInventory::getPricingType, pricingType);

        Page<MeteringInventory> page = new Page<>(pageIndex, pageSize);
        Page<MeteringInventory> page1 = meteringInventoryService.page(page, queryWrapper);

        return ResultUtil.success(page1);
    }

    @Operation(summary = "新增计量单位")
    @PostMapping("/ManInfo")
    public Result<String> addInfo(@RequestBody MeteringInventoryDTO meteringInventoryDTO,
                                  @RequestHeader("Create-Ap-Id") String createApId) {

        LambdaQueryWrapper<MeteringInventory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(MeteringInventory::getProjectName, meteringInventoryDTO.getProjectName());
        long count = meteringInventoryService.count(lambdaQueryWrapper);
        if (count > 0) {
            return ResultUtil.fail("名称已存在!");
        }

        MeteringInventory Ma = new MeteringInventory();
        BeanUtils.copyProperties(meteringInventoryDTO, Ma);
        String id = UUID.randomUUID().toString();
        Ma.setId(id);
        Ma.setCreateApId(createApId);

        boolean save = meteringInventoryService.save(Ma);
        if (save) {
            return ResultUtil.success("添加成功");
        }
        return ResultUtil.fail("添加失败");
    }

    @Operation(summary = "根据id删除计量单位")
    @GetMapping("/deleteAnId")
    public Result<String> deleteMetId(@RequestParam("id") String id) {
        boolean removeById = meteringInventoryService.removeById(id);
        if (removeById) {
            return ResultUtil.success("删除成功");
        }
        return ResultUtil.error("删除失败");
    }

    @Operation(summary = "根据id修改计量单位")
    @PostMapping("/updateAnId/{id}")
    public Result<String> updateManId(@RequestBody MeteringInventoryDTO meteringInventoryDTO,
                                      @PathVariable("id") String id) {
        MeteringInventory Met = new MeteringInventory();
        Met.setId(id);

        BeanUtils.copyProperties(meteringInventoryDTO, Met);

        boolean b = meteringInventoryService.updateById(Met);
        if (b) {
            return ResultUtil.success("修改成功");
        }
        return ResultUtil.fail("修改失败");
    }

    @Operation(summary = "根据单价总价或病害模块查询计量清单数据")
    @GetMapping("/getMeteringList")
    public Result<Page<MeteringInventory>> getDicListTree(@RequestParam("pageIndex") int pageIndex, @RequestParam("pageSize") int pageSize, @RequestParam(value = "DiseaseModule", required = false) String DiseaseModule, @RequestParam(value = "pricingType", required = false) String pricingType) {

        LambdaQueryWrapper<MeteringInventory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.apply("1=1")

                .eq(DiseaseModule != null && !DiseaseModule.isEmpty(), MeteringInventory::getDiseaseModule, DiseaseModule)
                .eq(pricingType != null && !pricingType.isEmpty(), MeteringInventory::getPricingType, pricingType);


        Page<MeteringInventory> page = new Page<>(pageIndex, pageSize);
        Page<MeteringInventory> page1 = meteringInventoryService.page(page, queryWrapper);
        return ResultUtil.success(page1);
    }


    @Operation(summary = "计量清单数据维护")
    @GetMapping("/getMeteringMaintenance")
    public Result<List<MeteringInventoryLevelVO>> getMeteringMaintenance(@RequestParam("projectNoSort") String projectNoSort) {
        QueryWrapper<MeteringInventory> queryWrapper = new QueryWrapper<MeteringInventory>()
                .select("id", "project_no", "parent_id", "LENGTH(project_no) disease_module")
                .apply("1=1").eq("pricing_type", "1");
        List<MeteringInventory> list = meteringInventoryService.list(queryWrapper);


        List<MeteringInventory> list1 = list.stream().filter(s -> s.getProjectNo().startsWith(projectNoSort)).toList();
        Map<Integer, List<MeteringInventory>> collect = list1.stream().collect(Collectors.groupingBy(MeteringInventory::getDiseaseModule));

        List<MeteringInventory> value;
        for (Map.Entry<Integer, List<MeteringInventory>> entry : collect.entrySet()) {
            value = entry.getValue();
            List<String> ids;
            for (MeteringInventory meteringInventory : value) {

                System.out.println(meteringInventory.getProjectNo());


                if (meteringInventory.getProjectNo().length() == 3 || meteringInventory.getProjectNo().length() == 4) {
                    LambdaUpdateWrapper<MeteringInventory> updateWrapper = new LambdaUpdateWrapper<MeteringInventory>()
                            .set(MeteringInventory::getParentId, "")
                            .eq(MeteringInventory::getId, meteringInventory.getId());
                    meteringInventoryService.update(updateWrapper);
                }


                List<MeteringInventory> list2 = list1.stream().filter(s -> s.getProjectNo().startsWith(meteringInventory.getProjectNo()) && (s.getProjectNo().length() == meteringInventory.getProjectNo().length() + 2 || s.getProjectNo().length() == meteringInventory.getProjectNo().length() + 3)).toList();
                if (!list2.isEmpty()) {

                    ids = list2.stream().map(MeteringInventory::getId).toList();
                    LambdaUpdateWrapper<MeteringInventory> lambdaUpdateWrapper = new LambdaUpdateWrapper<MeteringInventory>()
                            .set(MeteringInventory::getParentId, meteringInventory.getId())
                            .in(MeteringInventory::getId, ids);
                    meteringInventoryService.update(lambdaUpdateWrapper);

//                    Map<Integer, List<MeteringInventory>> collect1 = list2.stream().collect(Collectors.groupingBy(MeteringInventory::getDiseaseModule));
//                    int size = collect1.entrySet().size();
//                    if (size == 1) {
//                        ids = collect1.values().stream().map(meteringInventories -> meteringInventories.getFirst().getId()).toList();
//                        LambdaUpdateWrapper<MeteringInventory> lambdaUpdateWrapper = new LambdaUpdateWrapper<MeteringInventory>()
//                                .set(MeteringInventory::getParentId, meteringInventory.getId())
//                                .in(MeteringInventory::getId, ids);
//                        meteringInventoryService.update(lambdaUpdateWrapper);
//                    } else {
//
//                        List<MeteringInventory> value1;
//                        for (Map.Entry<Integer, List<MeteringInventory>> entry1 : collect1.entrySet()) {
//                            value1 = entry1.getValue();
//
//                            for (MeteringInventory meteringInventory1 : value1) {
//
//
//
//
//
//
//                            }
//
//
//
//
//                        }
//                    }
                }
            }
        }

        return null;
    }


    @Operation(summary = "获取计量清单结构")
    @GetMapping("/getMeteringStructure")
    public Result<List<MeteringInventoryLevelVO>> getMeteringStructure(
            @Schema(description = "计价类型") @RequestParam(value = "pricingType", required = false) String pricingType,
            @Schema(description = "单价（元）开始范围") @RequestParam(value = "unitPriceO", required = false) String unitPriceO,
            @Schema(description = "单价（元）结束范围") @RequestParam(value = "unitPriceT", required = false) String unitPriceT,
            @Schema(description = "合价（元）开始范围") @RequestParam(value = "totalPriceO", required = false) String totalPriceO,
            @Schema(description = "合价（元）结束范围") @RequestParam(value = "totalPriceT", required = false) String totalPriceT) {
        LambdaQueryWrapper<MeteringInventory> queryWrapper = new LambdaQueryWrapper<MeteringInventory>()
                .select(MeteringInventory::getId,
                        MeteringInventory::getProjectNo,
                        MeteringInventory::getProjectName,
//                        MeteringInventory::getProjectCharacteristic,
//                        MeteringInventory::getUnit,
//                        MeteringInventory::getAmount,
                        MeteringInventory::getUnitPrice,
                        MeteringInventory::getTotalPrice,
//                        MeteringInventory::getProjectType,
//                        MeteringInventory::getPricingType,
                        MeteringInventory::getParentId
//                        MeteringInventory::getDiseaseModule
                )
                .apply("1=1")
                .eq(StringUtils.isNotEmpty(pricingType), MeteringInventory::getPricingType, pricingType);
        List<MeteringInventory> list = meteringInventoryService.list(queryWrapper);


        List<MeteringInventory> list1 = list.stream().filter(f -> f.getParentId().isEmpty()).toList();

        List<MeteringInventoryLevelVO> list2 = new ArrayList<>();
        MeteringInventoryLevelVO meteringInventoryLevelVO;
        for (MeteringInventory meteringInventory : list1) {
            meteringInventoryLevelVO = new MeteringInventoryLevelVO();
            BeanUtils.copyProperties(meteringInventory, meteringInventoryLevelVO);

            meteringInventoryLevelVO.setStructureName(meteringInventory.getProjectNo() + meteringInventory.getProjectName());

            meteringInventoryLevelVO.setSubset(getSubset(meteringInventory.getId(), list,unitPriceO,unitPriceT,totalPriceO,totalPriceT));
            list2.add(meteringInventoryLevelVO);
        }
        return ResultUtil.success(list2);
    }

    public static List<MeteringInventoryLevelVO> getSubset(String id, List<MeteringInventory> list,
                                                           String unitPriceO,String unitPriceT,String totalPriceO,String totalPriceT) {

        List<MeteringInventory> list1 = list.stream().filter(menu -> menu.getParentId().equals(id)).toList();
        List<MeteringInventoryLevelVO> listRes = new ArrayList<>();
        if (!list1.isEmpty()) {
            MeteringInventoryLevelVO menuLevelVo;
            for (MeteringInventory menu : list1) {
                menuLevelVo = new MeteringInventoryLevelVO();
                BeanUtils.copyProperties(menu, menuLevelVo);
                menuLevelVo.setStructureName(menu.getProjectNo() + menu.getProjectName());


                if(menu.getUnitPrice() != null) {
                    if(StringUtils.isNotEmpty(unitPriceO) && menu.getUnitPrice().doubleValue() < Double.parseDouble(unitPriceO)){
                        continue;
                    }

                    if(StringUtils.isNotEmpty(unitPriceT) && menu.getUnitPrice().doubleValue() > Double.parseDouble(unitPriceT)){
                        continue;
                    }
                }
                if(menu.getTotalPrice() != null) {
                    if(StringUtils.isNotEmpty(totalPriceO) && menu.getTotalPrice().doubleValue() < Double.parseDouble(totalPriceO)){
                        continue;
                    }

                    if(StringUtils.isNotEmpty(totalPriceT) && menu.getTotalPrice().doubleValue() > Double.parseDouble(totalPriceT)){
                        continue;
                    }
                }


                menuLevelVo.setSubset(getSubset(menu.getId(), list,unitPriceO,unitPriceT,totalPriceO,totalPriceT));
                listRes.add(menuLevelVo);
            }
        }
        return listRes;
    }


}
